package dormouse.vfs.event;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * This class provides support for location change events.
 */
public class LocationChangeEventMixin implements
		IEventMixin<ILocationChangeListener, ILocationChangeEvent> {

	/** The executor. */
	private ThreadPoolExecutor exec = new ThreadPoolExecutor(5, 10, 5,
			TimeUnit.SECONDS, new ArrayBlockingQueue(50));

	/** The list of listeners to be notified. */
	private List<ILocationChangeListener> listenerList = new ArrayList<ILocationChangeListener>();

	/**
	 * Adds a file selection listener.
	 * 
	 * @param listener
	 *            the listener to be added.
	 */
	public void addListener(ILocationChangeListener listener) {
		listenerList.add(listener);
	}

	/**
	 * Removes a file selection listener.
	 * 
	 * @param listener
	 *            the listener to be removed.
	 */
	public void removeListener(ILocationChangeListener listener) {
		listenerList.remove(listener);
	}

	/**
	 * Notifies all registered listeners of file selection events.
	 * 
	 * @param event
	 *            the event to be broadcast.
	 */
	public void notify(ILocationChangeEvent event) {
		for (ILocationChangeListener listener : listenerList) {
			exec.submit(new Notifier(event, listener));
		}
	}

	/**
	 * This task is responsible for notifying listeners of file selection
	 * events.
	 */
	class Notifier implements Callable {

		/** The event to be broadcast. */
		private ILocationChangeEvent event;

		/** The listener to be notified. */
		private ILocationChangeListener listener;

		/**
		 * Constructor.
		 * 
		 * @param event
		 *            the event to be broadcast.
		 * @param listener
		 *            the listener to be notified.
		 */
		public Notifier(final ILocationChangeEvent event,
				final ILocationChangeListener listener) {
			this.event = event;
			this.listener = listener;
		}

		@Override
		public Object call() throws Exception {
			listener.locationChanged(event);
			return null;
		}

	}
}
